package org.heart.config.interceptor;

import org.heart.common.exection.TokenValidationException;
import org.heart.config.UserContext;
import org.heart.utils.JwtUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class Interceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(Interceptor.class);


    @Resource
    private JwtUtils lmlJwtUtils;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        log.info("进入自定义拦截器！");

        String path = request.getRequestURI();


        log.info("请求路径：{}，未被放行需要检验 token！",path);

        String token = request.getHeader("Authorization");

        if (token == null || token.isEmpty()) {
            throw new TokenValidationException("Token 校验失败！");
        }

        boolean isValid = validateToken(token);

        if(!isValid){
            throw new TokenValidationException("Token 校验失败！");
        }

        /**
         * 解析token
         *
         * 并且将用户ID 存放在本地线程变量中
         */
        String userId = lmlJwtUtils.parseToken(token);

        UserContext.setUserId(userId);

        return true;
    }

    /**
     * 请求处理完成之后的逻辑
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    /**
     * 请求处理完成之后的逻辑
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

    /**
     * 校验token是否有效
     */
    private boolean validateToken(String token) {
        return lmlJwtUtils.isTokenExpired(token);
    }

}
